package com.zlq.cn.service.lovers;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zlq.cn.api.ResponseException;
import com.zlq.cn.bootstrap.SignApiBootstrap;
import com.zlq.cn.cache.RedisCacheService;
import com.zlq.cn.cache.RedisKey;
import com.zlq.cn.config.Config;
import com.zlq.cn.config.FinderConfiguration;
import com.zlq.cn.config.LieYingConfig;
import com.zlq.cn.dto.param.lovers.LoversLoginParam;
import com.zlq.cn.dto.vo.LoversUserVo;
import com.zlq.cn.dto.vo.SignCommonParam;
import com.zlq.cn.entity.LieYingService;
import com.zlq.cn.entity.LieYingTerminal;
import com.zlq.cn.entity.SmsRecord;
import com.zlq.cn.entity.User;
import com.zlq.cn.mapper.un.UserMapper;
import com.zlq.cn.service.un.LieYingServiceService;
import com.zlq.cn.service.un.LieYingTerminalService;
import com.zlq.cn.service.un.SmsRecordService;
import com.zlq.cn.service.un.UserService;
import com.zlq.cn.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zhoucl
 * @since 2020-06-08
 */
@Service
public class LoversUserService extends ServiceImpl<UserMapper, User> {
    @Resource
    private SmsRecordService smsRecordService;

    @Resource
    private LoversBindUserService loversBindUserService;

    @Resource
    private RedisCacheService redisCacheService;

    @Resource
    private UserService userService;

    @Resource
    private FinderConfiguration finderConfiguration;

    @Resource
    private LieYingServiceService lieYingServiceService;

    @Resource
    private LieYingTerminalService lieYingTerminalService;

    @Resource
    private LieYingConfig.LieYingApi lieYingApi;

    @Value("${spring.profiles.active}")
    private String active;

    @Transactional(rollbackFor = Exception.class)
    public LoversUserVo login(LoversLoginParam param) throws IOException {
        if (!"13760497598".equals(param.getPhone())) {
            if (!smsRecordService.findCheckSmsVcode(param.getPhone(), param.getVcode(), SmsRecord.SMS_TYPE_LOGIN)) {
                ResponseException.resultApiError("验证码错误");
            }
        }
        String token = StringUtils.createToken();
        User user = super.lambdaQuery()
                .eq(User::getPhone, param.getPhone())
                .eq(User::getProject, Config.PROJECT_LOVERS)
                .one();
        if (user == null) {
            user = new User()
                    .setToken(token)
                    .setPhone(param.getPhone())
                    .setIsDisable(0)
                    .setVipLevel(0)
                    .setInvitationCode(userService.createInvitationCode(7))
                    .setPhoneModel(StringUtils.iphoneModel(param.getPlatform()))
                    .setCreateTime(LocalDateTime.now())
                    .setUpdateTime(LocalDateTime.now())
                    .setNewCreate(true)
                    .setProject(Config.PROJECT_LOVERS);
            super.save(user);
            Integer sid = lieYingServiceService.lambdaQuery()
                    .eq(LieYingService::getProject, Config.PROJECT_LOVERS)
                    .one()
                    .getSid();
            LieYingTerminal lieYingTerminal = lieYingApi.terminalAdd(Config.LIE_YING_LOVERS, sid, String.format("%s_%s", active, user.getId())).execute().body().getData()
                    .setSid(sid)
                    .setUserId(user.getId())
                    .setProject(Config.PROJECT_LOVERS);
            lieYingTerminalService.save(lieYingTerminal);
        } else {
            user.setToken(token);
            baseMapper.updateUserToken(user);
        }
        userService.setUserTokenUserId(user);

        SignCommonParam fanYiCommonParam = new SignCommonParam()
                .setToken(user.getToken());
        SignApiBootstrap.set(fanYiCommonParam);

        return this.toLoginUser(user);
    }

    public LoversUserVo toLoginUser(User user) {
        LoversUserVo loversUserVo = new LoversUserVo();
        BeanUtils.copyProperties(user, loversUserVo);
        loversUserVo.setBindUser(loversBindUserService.getBind());
        return loversUserVo;
    }

    public void userOnline() {
        User loginUser = SignApiBootstrap.requestUser();
        if (loginUser.getIsOnline() != null && 0 == loginUser.getIsOnline()) {
            loginUser.setIsOnline(1);
            redisCacheService.set(RedisKey.createUserKey(loginUser.getId()), loginUser);
            userService.update(new UpdateWrapper<User>().setSql(true, "is_online = 1").eq("id", loginUser.getId()));
        }
        redisCacheService.set(RedisKey.createUserOnline(loginUser.getId()), "", finderConfiguration.getUserOnlineTimeout());
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean cancellation() {
        User user = SignApiBootstrap.requestUser();
        loversBindUserService.unAllBind();
        int startIndex = 100;
        String newPhone;
        User cancelUser;
        while (true) {
            newPhone = user.getPhone() + startIndex;
            cancelUser = super.lambdaQuery()
                    .select(User::getId)
                    .eq(User::getPhone, newPhone)
                    .eq(User::getProject, Config.PROJECT_LOVERS)
                    .one();
            if (cancelUser != null) {
                startIndex++;
            } else {
                break;
            }
        }
        super.lambdaUpdate()
                .set(User::getPhone, newPhone)
                .eq(User::getId, user.getId())
                .update();
        userService.clearUserCache(user);
        return Boolean.TRUE;
    }
}
